package com.donleo.stmg.entity.service.impl;

import com.alibaba.excel.EasyExcelFactory;
import com.alibaba.excel.ExcelWriter;
import com.alibaba.excel.metadata.Sheet;
import com.donleo.stmg.common.api.CommonResult;
import com.donleo.stmg.entity.mapper.UserMapper;
import com.donleo.stmg.entity.model.User;
import com.donleo.stmg.entity.model.Word;
import com.donleo.stmg.entity.mapper.WordMapper;
import com.donleo.stmg.entity.service.WordService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.donleo.stmg.entity.vo.WordEnum;
import com.donleo.stmg.entity.vo.WordExcelVo;
import com.donleo.stmg.entity.vo.WordVo;
import com.donleo.stmg.relation.mapper.WordRecordMapper;
import com.donleo.stmg.relation.model.WordRecord;
import com.donleo.stmg.utils.CommonPath;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

/**
 * <p>
 * 单词表 服务实现类
 * </p>
 *
 * @author liangd
 * @since 2020-12-21
 */
@Service
public class WordServiceImpl extends ServiceImpl<WordMapper, Word> implements WordService {

    @Autowired
    private UserMapper userMapper;

    @Autowired
    private WordMapper wordMapper;

    @Autowired
    private WordRecordMapper wordRecordMapper;

    @Override
    public CommonResult add(String userCode, Word word) {
        User user = userMapper.findByCode(userCode);
        //根据英文名称查询单词
        List<WordRecord> list = wordRecordMapper.selectByEngLish(userCode, word.getEnglish());
        //如果数据库有数据，表示用户已经发布该单词了
        if (list.size() > 0) {
            return CommonResult.validateFailed();
        } else {
            word.setAuthor(user.getUsername());
            word.setCommitTime(new Date());
            int i = wordMapper.insert(word);
            WordRecord wordRecord = new WordRecord();
            wordRecord.setUserCode(userCode);
            wordRecord.setWordId(word.getId());
            wordRecord.setType(WordEnum.RECORD.getValue());
            wordRecordMapper.insert(wordRecord);
            if (i > 0) {
                return CommonResult.success(i);
            }
            return CommonResult.failed();
        }
    }

    @Override
    public CommonResult delete(Integer id) {
        int i = wordMapper.deleteById(id);
        wordRecordMapper.deleteByWordId(id);
        if (i > 0) {
            return CommonResult.success(i);
        }
        return CommonResult.failed();
    }

    @Override
    public CommonResult updateWord(String userCode, Word word) {
        //根据英文名称查询单词
        List<WordRecord> list = wordRecordMapper.selectByEngLish(userCode, word.getEnglish());
        //如果数据库有数据，表示用户已经发布该单词了
        if (list.size() > 0) {
            return CommonResult.validateFailed();
        } else {
            int i = wordMapper.updateById(word);
            if (i > 0) {
                return CommonResult.success(i);
            }
            return CommonResult.failed();
        }
    }

    @Override
    public Word findById(Integer id) {
        return wordMapper.selectById(id);
    }

    @Override
    public List<WordVo> findAll(String userCode, WordVo wordVo) {
        List<Word> wordList = wordMapper.findAll(wordVo);
        return setWordVo(userCode, wordList);
    }

    @Override
    public long getCount(WordVo wordVo) {
        return wordMapper.getCount(wordVo);
    }

    @Override
    public CommonResult userPraise(Integer praiseStatus, WordRecord wordRecord) {
        int count = 0;
        if (praiseStatus.equals(WordEnum.ENABLE_PRAISE_STATUS.getValue())) {
            //新增点赞记录
            WordRecord wr = new WordRecord();
            wr.setUserCode(wordRecord.getUserCode());
            wr.setWordId(wordRecord.getWordId());
            wr.setType(WordEnum.PRAISE_RECODE.getValue());
            count = wordRecordMapper.insert(wr);
        } else if (praiseStatus.equals(WordEnum.ABLE_PRAISE_STATUS.getValue())) {
            //移除点赞记录
            count = wordRecordMapper.deleteByType(wordRecord.getUserCode(), wordRecord.getWordId(), WordEnum.PRAISE_RECODE.getValue());
        }
        if (count > 0) {
            return CommonResult.success(count);
        }
        return CommonResult.failed();
    }

    @Override
    public CommonResult userCollections(Integer collectionStatus, WordRecord wordRecord) {
        int count = 0;
        if (collectionStatus.equals(WordEnum.ENABLE_PRAISE_STATUS.getValue())) {
            //新增收藏记录
            WordRecord wr = new WordRecord();
            wr.setUserCode(wordRecord.getUserCode());
            wr.setWordId(wordRecord.getWordId());
            wr.setType(WordEnum.COLLECTION_RECORD.getValue());
            count = wordRecordMapper.insert(wr);
        } else if (collectionStatus.equals(WordEnum.ABLE_PRAISE_STATUS.getValue())) {
            //移除收藏记录
            count = wordRecordMapper.deleteByType(wordRecord.getUserCode(), wordRecord.getWordId(), WordEnum.COLLECTION_RECORD.getValue());
        }
        if (count > 0) {
            return CommonResult.success(count);
        }
        return CommonResult.failed();
    }

    @Override
    public List<WordVo> findUserWord(String userCode, Integer type, WordVo wordVo) {
        List<Word> wordList = wordMapper.findUserWord(userCode, type, wordVo);
        return setWordVo(userCode, wordList);
    }

    @Override
    public long getUserWordCount(String userCode, Integer type, WordVo wordVo) {
        return wordMapper.getUserWordCount(userCode, type, wordVo);
    }

    @Override
    public void exportExcel(List<Word> word, HttpServletResponse response) {
        try {
            String path = CommonPath.WORD_EXCEL_PATH.getValue();
            String fileName = System.currentTimeMillis() + ".xlsx";
            //创建文件
            File file = new File(path + fileName);
            OutputStream outputStream = new FileOutputStream(file);
            ExcelWriter writer = EasyExcelFactory.getWriter(outputStream);
            //只生成一个sheet
            Sheet sheet = new Sheet(1, 0, WordExcelVo.class);
            sheet.setSheetName("我的收藏");
            //写数据
            writer.write(writeWord(word), sheet);
            writer.finish();
            outputStream.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /**
     * 赋值
     *
     * @param userCode 用户编号
     * @param wordList 单词列表
     * @return List<WordVo>
     */
    private List<WordVo> setWordVo(String userCode, List<Word> wordList) {
        List<WordVo> collect = wordList.stream().map(word -> {
            WordVo vo = new WordVo();
            BeanUtils.copyProperties(word, vo);
            //查询是否有点赞记录
            WordRecord w1 = wordRecordMapper.selectByType(userCode, word.getId(), WordEnum.PRAISE_RECODE.getValue());
            if (w1 != null) {
                vo.setPraiseStatus(WordEnum.ABLE_PRAISE_STATUS.getValue());
            } else {
                vo.setPraiseStatus(WordEnum.ENABLE_PRAISE_STATUS.getValue());
            }
            //查询是否有收藏记录
            WordRecord w2 = wordRecordMapper.selectByType(userCode, word.getId(), WordEnum.COLLECTION_RECORD.getValue());
            if (w2 != null) {
                vo.setCollectionStatus(WordEnum.ABLE_PRAISE_STATUS.getValue());
            } else {
                vo.setCollectionStatus(WordEnum.ENABLE_PRAISE_STATUS.getValue());
            }
            //点赞数量
            Integer count = wordRecordMapper.getPriseCount(word.getId(), WordEnum.PRAISE_RECODE.getValue());
            vo.setNumber(count);
            return vo;
        }).collect(Collectors.toList());
        return collect;
    }

    /**
     * 赋值excel表格的数据
     *
     * @param word List<Word>
     * @return List<WordExcelVo>
     */
    private List<WordExcelVo> writeWord(List<Word> word) {
        List<WordExcelVo> wList = new ArrayList<>();
        for (Word aWord : word) {
            WordExcelVo wordExcelVo = WordExcelVo.builder()
                    .id(aWord.getId())
                    .chinese(aWord.getChinese())
                    .english(aWord.getEnglish())
                    .author(aWord.getAuthor())
                    .commitTime(aWord.getCommitTime())
                    .number(aWord.getNumber())
                    .build();
            wList.add(wordExcelVo);
        }
        return wList;
    }
}
